Description
给定一棵 $n$ 个节点的树,定义树上两个节点 $a$、$b$ 的距离为从 $a$ 走到 $b$ 需要经过的边数。在任意一个节点建立消防站,可以覆盖到与其距离不超过 $2$ 的所有节点。求覆盖到树上每个节点最少需要的消防站个数。
数据范围:$n<=1000$
Solution
树形dp
设 $f[i][0-4]$ 从 $i$ 这个节点向上覆盖 $2$ 到 $-2$ 层需要建立的最小消防站数。向上覆盖 $1$ 层是指覆盖 $i$ 所在的整个子树和 $i$ 的父亲。向上覆盖 $-1$ 层是指覆盖 $i$ 所在的子树除去 $i$。
可以看出 $f[i][0] ≥ f[i][1] ≥…≥ f[i][4]$
设 $s$ 表示节点 $i$ 的儿子;$t$ 是 $i$ 的儿子且 $t≠s$。
$f[i][0]=1+∑f[s][4]$
$f[i][1]=min$ { $f[s][0]+∑f[t][3]$ } 和 $f[i][0]$ 的最小值。
$f[i][2]=min$ { $f[s][1]+∑f[t][2]$ } 和 $f[i][1]$ 的最小值。
$f[i][3]=∑f[s][2]$ 和 $f[i][2]$ 的最小值。
$f[i][4]=∑f[s][3]$ 和 $f[i][3]$ 的最小值。
Code
1 |
|
贪心
每次选择一个深度最深的节点,想要覆盖这个节点,就需要在它的 兄弟/父亲/爷爷 中建立一个消防站。画图可以发现在其爷爷节点建立消防站可以覆盖到所有其他节点。
对所有节点进行排序,顺序遍历,取出 没有被覆盖过 的节点,在其爷爷节点建立一个消防站。
Code
1 |
|